use std::ops::{Generator, GeneratorState};
use std::pin::Pin;

/// 生成器
#[cfg(test)]
mod tests {
    use super::*;
    use std::mem;

    #[test]
    fn test_generators() {
        super::start();
        println!("{:?}", Export::field_names());

        let mut v: Vec<i32> = vec![1, 2];
        println!("{:p}", &v);

        let old_v = mem::replace(&mut v, vec![3, 4, 5]);
        assert_eq!(2, old_v.len());
        assert_eq!(3, v.len());

        println!("{:p}", &old_v);
        println!("{:p}", &v);
    }
}

pub fn start() {
    // 生成器
    let mut gen = || {
        yield 1;
        yield 2;
        yield 3;
        return 4;
    };
    loop {
        match Pin::new(&mut gen).resume(()) {
            GeneratorState::Yielded(v) => println!("v = {}", v),
            GeneratorState::Complete(v) => {
                println!("complete {}", v);
                break;
            }
        }
    }
}

macro_rules! zoom_and_enhance {
    (struct $name:ident { $($fname:ident : $ftype:ty),* }) => {
        struct $name {
            $($fname : $ftype),*
        }

        impl $name {
            fn field_names() -> &'static [&'static str] {
                static NAMES: &'static [&'static str] = &[$(stringify!($fname)),*];
                NAMES
            }
        }
    }
}

zoom_and_enhance! {
struct Export {
    first_name: String,
    last_name: String,
    gender: String,
    date_of_birth: String,
    address: String
}
}
